<!--3D柱状图-->

<template>
  <div class="w-h-full">
    <!--组件遮罩层，用于在设计器中显示-->
    <div v-if="shade" class="shade"></div>

    <div v-resize="resizeHandle" style="width: 100%; height: 100%;">
      <div :id="'chart-'+component.id+'-'+chartDomNum" class="w-h-full"></div>
    </div>
  </div>
</template>

<script>

import FuncCompMixin from '@/mixin/FuncCompMixin'
import ChartCompMixin from '@/mixin/ChartCompMixin'
import PnDesigner from '@/utils/PnDesigner'

const _this = {
  name: 'Bar3DChart', // 此名称必须填写，且必须与组件文件名相同
  mixins: [FuncCompMixin, ChartCompMixin],
  attr: {
    version: '1.0',
    configDataTemp: Object.assign({

      // 组件相关配置属性，Echarts图表组件的相关配置属性，必须在chartOption对象下定义
      chartOption: {
        // pn_chart_type: 'echarts-gl', // 此变量标识此组件是一个3D组件，不可删除

        tooltip: PnDesigner.buildTooltipConfigData({
          trigger: 'item'
        }),
        visualMap: [],
        grid3D: {
          show: true,
          boxWidth: 200,
          boxHeight: 100,
          boxDepth: 100,
          viewControl: {
            autoRotate: false,
            autoRotateDirection: 'cw',
            distance: 300,
            alpha: 30,
            beta: 30
          },
          light: {
            main: {
              color: '#fff',
              intensity: 1,
              shadow: true,
              shadowQuality: 'medium',
              alpha: 30,
              beta: 30
            },
            ambient: {
              intensity: 0.3
            }
          },
          axisPointer: {
            lineStyle: {
              color: '#ff9800',
              opacity: 1,
              width: 1
            },
            label: {
              show: true,
              formatter: '(value, valueAll) => {\n  return Math.floor(value)\n}',
              textStyle: {
                color: '#ff9800',
                fontSize: 14
              }
            }
          }
        },
        xAxis3D: {
          nameGap: 30,
          name: '',
          nameTextStyle: {
            color: 'rgb(144, 160, 174)',
            fontSize: 14
          },
          axisLine: {
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              width: 1,
              opacity: 1
            }
          },
          axisLabel: {
            show: true,
            margin: 16,
            textStyle: {
              color: 'rgb(144, 160, 174)',
              fontSize: 14
            }
          },
          axisTick: {
            show: false,
            length: 5,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          },
          splitArea: {
            show: false,
            areaStyle: {
              color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']
            }
          }
        },
        yAxis3D: {
          nameGap: 30,
          name: '',
          nameTextStyle: {
            color: 'rgb(144, 160, 174)',
            fontSize: 14
          },
          axisLine: {
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              width: 1,
              opacity: 1
            }
          },
          axisLabel: {
            show: true,
            margin: 8,
            textStyle: {
              color: 'rgb(144, 160, 174)',
              fontSize: 14
            }
          },
          axisTick: {
            show: true,
            length: 5,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          }
        },
        zAxis3D: {
          nameGap: 30,
          name: '',
          nameTextStyle: {
            color: 'rgb(144, 160, 174)',
            fontSize: 14
          },
          axisLine: {
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              width: 1,
              opacity: 1
            }
          },
          axisLabel: {
            show: true,
            margin: 12,
            textStyle: {
              color: 'rgb(144, 160, 174)',
              fontSize: 14
            }
          },
          axisTick: {
            show: true,
            length: 5,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(255, 255, 255, 0.1)',
              opacity: 1,
              width: 1
            }
          }
        },
        series: {
          name: '财务报表',
          bevelSize: 0, // 圆角
          itemStyle: {
            color: '',
            opacity: 1
          },
          label: {
            show: true,
            distance: 3,
            formatter: '(params) => {\n  return params.value[2]\n}',
            textStyle: {
              color: 'rgb(144, 160, 174)',
              fontSize: 16
            }
          },
          shading: 'lambert'
        }
      }

    }, PnDesigner.buildFuncCompDatasourceField({ // 如果组件需要配置数据源，则需要调用此函数构建数据源字段对象
      ds_resultObjTemplate: [
        {
          field: 'x',
          remark: 'x轴标签'
        },
        {
          field: 'y',
          remark: 'y轴标签'
        },
        {
          field: 'v',
          remark: '数值'
        },
        {
          field: 'itemStyle',
          remark: '柱子样式扩展'
        }
      ],
      ds_resultObj: [
        {x: '星期一', y: '销售量', v: 300, itemStyle: {color: '#f44336'}},
        {x: '星期二', y: '销售量', v: 430},
        {x: '星期三', y: '销售量', v: 250},
        {x: '星期四', y: '销售量', v: 500},
        {x: '星期五', y: '销售量', v: 540},
        {x: '星期一', y: '净利润', v: 130},
        {x: '星期二', y: '净利润', v: 230},
        {x: '星期三', y: '净利润', v: 100},
        {x: '星期四', y: '净利润', v: 470},
        {x: '星期五', y: '净利润', v: 500}
      ],
      ds_useFilter: true, // 是否使用过滤器，默认不使用
      ds_useTimer: true, // 是否开启定时器配置，默认不开启
    }), PnDesigner.buildFuncCompGlobalField(), PnDesigner.buildEchartCompCustomOption(), PnDesigner.buildFuncCompInteractionConfiguration())
  },
  data() {
    return {}
  },
  mounted() {
    this.init();

    this.setTimer(() => { //定时器，如果当前组件不使用定时器，可以将此段代码删除
      this.init()
    })
  },
  methods: {
    init() { // 组价初始化函数，函数名必须使用init，不可更改
      this.initDatasource(() => {
        this.chart.setOption(this.chartOption);
        this.runCustomGlobalJsCode();
        this.runDataItemClickJsCode()
      }, (result) => {
        this.chart.setOption(this.chartOption);
        this.runCustomGlobalJsCode();
        this.runDataItemClickJsCode()
      });
    }
  },
  computed: {
    chartOption() {
      let seriesData = [];
      let resultObj = this.runCustomFilter(this.component.compConfigData.ds_resultObj)

      let xData = this.$PnUtil.groupArray(resultObj, 'x').map((item) => {
        return item.type
      });
      let yData = this.$PnUtil.groupArray(resultObj, 'y').map((item) => {
        return item.type
      });

      this.$PnUtil.groupArray(resultObj, 'y').forEach((yItem, yItemIndex) => {
        for (let i = 0; i < yItem.list.length; i++) {
          seriesData.push({
            name: yItem.type,
            value: [i, yItemIndex, yItem.list[i].v],
            itemStyle: yItem.list[i].itemStyle ? yItem.list[i].itemStyle : null
          })
        }
      })

      let option = {
        tooltip: PnDesigner.buildTooltipChartOption(this.component.compConfigData.chartOption.tooltip),
        visualMap: this.component.compConfigData.chartOption.visualMap,
        grid3D: {
          show: this.component.compConfigData.chartOption.grid3D.show,
          boxWidth: this.component.compConfigData.chartOption.grid3D.boxWidth,
          boxHeight: this.component.compConfigData.chartOption.grid3D.boxHeight,
          boxDepth: this.component.compConfigData.chartOption.grid3D.boxDepth,
          viewControl: {
            autoRotate: this.component.compConfigData.chartOption.grid3D.viewControl.autoRotate,
            autoRotateDirection: this.component.compConfigData.chartOption.grid3D.viewControl.autoRotateDirection,
            distance: this.component.compConfigData.chartOption.grid3D.viewControl.distance,
            alpha: this.component.compConfigData.chartOption.grid3D.viewControl.alpha,
            beta: this.component.compConfigData.chartOption.grid3D.viewControl.beta
          },
          light: {
            main: {
              color: this.component.compConfigData.chartOption.grid3D.light.main.color,
              intensity: this.component.compConfigData.chartOption.grid3D.light.main.intensity,
              shadow: this.component.compConfigData.chartOption.grid3D.light.main.shadow,
              shadowQuality: this.component.compConfigData.chartOption.grid3D.light.main.shadowQuality,
              alpha: this.component.compConfigData.chartOption.grid3D.light.main.alpha,
              beta: this.component.compConfigData.chartOption.grid3D.light.main.beta
            },
            ambient: {
              intensity: this.component.compConfigData.chartOption.grid3D.light.ambient.intensity
            }
          },
          axisPointer: {
            lineStyle: {
              color: this.component.compConfigData.chartOption.grid3D.axisPointer.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.grid3D.axisPointer.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.grid3D.axisPointer.lineStyle.width
            },
            label: {
              show: this.component.compConfigData.chartOption.grid3D.axisPointer.label.show,
              formatter: this.component.compConfigData.chartOption.grid3D.axisPointer.label.formatter ?
                  eval(this.component.compConfigData.chartOption.grid3D.axisPointer.label.formatter) : (value, valueAll) => {return Math.floor(value)},
              textStyle: {
                color: this.component.compConfigData.chartOption.grid3D.axisPointer.label.textStyle.color,
                fontSize: this.component.compConfigData.chartOption.grid3D.axisPointer.label.textStyle.fontSize
              }
            }
          }
        },
        xAxis3D: {
          type: 'category',
          nameGap: this.component.compConfigData.chartOption.xAxis3D.nameGap,
          name: this.component.compConfigData.chartOption.xAxis3D.name,
          nameTextStyle: {
            color: this.component.compConfigData.chartOption.xAxis3D.nameTextStyle.color,
            fontSize: this.component.compConfigData.chartOption.xAxis3D.nameTextStyle.fontSize
          },
          axisLine: {
            lineStyle: {
              color: this.component.compConfigData.chartOption.xAxis3D.axisLine.lineStyle.color,
              width: this.component.compConfigData.chartOption.xAxis3D.axisLine.lineStyle.width,
              opacity: this.component.compConfigData.chartOption.xAxis3D.axisLine.lineStyle.opacity
            }
          },
          axisLabel: {
            show: this.component.compConfigData.chartOption.xAxis3D.axisLabel.show,
            margin: this.component.compConfigData.chartOption.xAxis3D.axisLabel.margin,
            textStyle: {
              color: this.component.compConfigData.chartOption.xAxis3D.axisLabel.textStyle.color,
              fontSize: this.component.compConfigData.chartOption.xAxis3D.axisLabel.textStyle.fontSize
            }
          },
          axisTick: {
            show: this.component.compConfigData.chartOption.xAxis3D.axisTick.show,
            length: this.component.compConfigData.chartOption.xAxis3D.axisTick.length,
            lineStyle: {
              color: this.component.compConfigData.chartOption.xAxis3D.axisTick.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.xAxis3D.axisTick.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.xAxis3D.axisTick.lineStyle.width
            }
          },
          splitLine: {
            show: this.component.compConfigData.chartOption.xAxis3D.splitLine.show,
            lineStyle: {
              color: this.component.compConfigData.chartOption.xAxis3D.splitLine.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.xAxis3D.splitLine.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.xAxis3D.splitLine.lineStyle.width
            }
          },
          splitArea: {
            show: this.component.compConfigData.chartOption.xAxis3D.splitArea.show,
            areaStyle: {
              color: this.component.compConfigData.chartOption.xAxis3D.splitArea.areaStyle.color
            }
          },
          data: xData
        },
        yAxis3D: {
          type: 'category',
          nameGap: this.component.compConfigData.chartOption.yAxis3D.nameGap,
          name: this.component.compConfigData.chartOption.yAxis3D.name,
          nameTextStyle: {
            color: this.component.compConfigData.chartOption.yAxis3D.nameTextStyle.color,
            fontSize: this.component.compConfigData.chartOption.yAxis3D.nameTextStyle.fontSize
          },
          axisLine: {
            lineStyle: {
              color: this.component.compConfigData.chartOption.yAxis3D.axisLine.lineStyle.color,
              width: this.component.compConfigData.chartOption.yAxis3D.axisLine.lineStyle.width,
              opacity: this.component.compConfigData.chartOption.yAxis3D.axisLine.lineStyle.opacity
            }
          },
          axisLabel: {
            show: this.component.compConfigData.chartOption.yAxis3D.axisLabel.show,
            margin: this.component.compConfigData.chartOption.yAxis3D.axisLabel.margin,
            textStyle: {
              color: this.component.compConfigData.chartOption.yAxis3D.axisLabel.textStyle.color,
              fontSize: this.component.compConfigData.chartOption.yAxis3D.axisLabel.textStyle.fontSize
            }
          },
          axisTick: {
            show: this.component.compConfigData.chartOption.yAxis3D.axisTick.show,
            length: this.component.compConfigData.chartOption.yAxis3D.axisTick.length,
            lineStyle: {
              color: this.component.compConfigData.chartOption.yAxis3D.axisTick.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.yAxis3D.axisTick.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.yAxis3D.axisTick.lineStyle.width
            }
          },
          splitLine: {
            show: this.component.compConfigData.chartOption.yAxis3D.splitLine.show,
            lineStyle: {
              color: this.component.compConfigData.chartOption.yAxis3D.splitLine.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.yAxis3D.splitLine.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.yAxis3D.splitLine.lineStyle.width
            }
          },
          data: yData
        },
        zAxis3D: {
          type: 'value',
          nameGap: this.component.compConfigData.chartOption.zAxis3D.nameGap,
          name: this.component.compConfigData.chartOption.zAxis3D.name,
          nameTextStyle: {
            color: this.component.compConfigData.chartOption.zAxis3D.nameTextStyle.color,
            fontSize: this.component.compConfigData.chartOption.zAxis3D.nameTextStyle.fontSize
          },
          axisLine: {
            lineStyle: {
              color: this.component.compConfigData.chartOption.zAxis3D.axisLine.lineStyle.color,
              width: this.component.compConfigData.chartOption.zAxis3D.axisLine.lineStyle.width,
              opacity: this.component.compConfigData.chartOption.zAxis3D.axisLine.lineStyle.opacity
            }
          },
          axisLabel: {
            show: this.component.compConfigData.chartOption.zAxis3D.axisLabel.show,
            margin: this.component.compConfigData.chartOption.zAxis3D.axisLabel.margin,
            textStyle: {
              color: this.component.compConfigData.chartOption.zAxis3D.axisLabel.textStyle.color,
              fontSize: this.component.compConfigData.chartOption.zAxis3D.axisLabel.textStyle.fontSize
            }
          },
          axisTick: {
            show: this.component.compConfigData.chartOption.zAxis3D.axisTick.show,
            length: this.component.compConfigData.chartOption.zAxis3D.axisTick.length,
            lineStyle: {
              color: this.component.compConfigData.chartOption.zAxis3D.axisTick.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.zAxis3D.axisTick.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.zAxis3D.axisTick.lineStyle.width
            }
          },
          splitLine: {
            show: this.component.compConfigData.chartOption.zAxis3D.splitLine.show,
            lineStyle: {
              color: this.component.compConfigData.chartOption.zAxis3D.splitLine.lineStyle.color,
              opacity: this.component.compConfigData.chartOption.zAxis3D.splitLine.lineStyle.opacity,
              width: this.component.compConfigData.chartOption.zAxis3D.splitLine.lineStyle.width
            }
          },
        },
        series: [
          {
            type: 'bar3D',
            name: this.component.compConfigData.chartOption.series.name,
            bevelSize: this.component.compConfigData.chartOption.series.bevelSize, // 圆角
            itemStyle: {
              color: this.component.compConfigData.chartOption.series.itemStyle.color,
              opacity: this.component.compConfigData.chartOption.series.itemStyle.opacity
            },
            label: {
              show: this.component.compConfigData.chartOption.series.label.show,
              distance: this.component.compConfigData.chartOption.series.label.distance,
              formatter: this.component.compConfigData.chartOption.series.label.formatter ?
                  eval(this.component.compConfigData.chartOption.series.label.formatter) : (params) => {return params.value[2]},
              textStyle: {
                color: this.component.compConfigData.chartOption.series.label.textStyle.color,
                fontSize: this.component.compConfigData.chartOption.series.label.textStyle.fontSize
              }
            },
            // emphasis: {
            //   // label: {
            //   //   fontSize: 20,
            //   //   color: '#900'
            //   // },
            //   itemStyle: {
            //     color: null
            //   }
            // },
            data: seriesData,
            shading: this.component.compConfigData.chartOption.series.shading
          }
        ]
      };

      // 下面这一段代码用于合并组件的扩展配置，如果组件不需要扩展配置，可以删掉
      option = this.$PnDesigner.mergeChartCustomOption(option, this.component.compConfigData.customOption);

      return option;
    }
  }
};

export default _this
</script>

<style scoped>

</style>
